<?php

namespace app\api\controller;

use app\admin\model\AreaFive;
use app\admin\model\AreaFour;
use app\common\controller\Api;
use app\common\model\Area;
use app\common\model\Version;
use fast\Random;
use Obs\ObsClient;
use Obs\ObsException;
use think\Config;
use think\Db;
use think\Validate;

/**
 * 公共接口
 */
class Common extends Api
{
    protected $noNeedLogin = ['*'];
    protected $noNeedRight = ['*'];
    protected $noNeedSite  = ['*'];
    protected $noNeedCheck = ['*'];

    /**
     * 加载初始化
     *
     * @param string $version 版本号
     * @param string $lng     经度
     * @param string $lat     纬度
     */
    public function init()
    {
        if ($version = $this->request->request('version')) {
            $lng = $this->request->request('lng');
            $lat = $this->request->request('lat');
            $content = [
                'citydata'    => Area::getCityFromLngLat($lng, $lat),
                'versiondata' => Version::check($version),
                'uploaddata'  => Config::get('upload'),
                'coverdata'   => Config::get("cover"),
            ];
            $this->success('', $content);
        } else {
            $this->error(__('Invalid parameters'));
        }
    }

    /**
     * 上传文件
     * @ApiMethod (POST)
     * @param File $file 文件流
     */
    public function upload()
    {
        $file = $this->request->file('file');
        if (empty($file)) {
            $this->error(__('No file upload or server upload limit exceeded'));
        }

        //判断是否已经存在附件
        $sha1 = $file->hash();

        $upload = Config::get('upload');

        preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
        $type = strtolower($matches[2]);
        $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
        $size = (int)$upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
        $fileInfo = $file->getInfo();
        $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
        $suffix = $suffix ? $suffix : 'file';

        $mimetypeArr = explode(',', strtolower($upload['mimetype']));
        $typeArr = explode('/', $fileInfo['type']);

        //验证文件后缀
        if ($upload['mimetype'] !== '*' &&
            (
                !in_array($suffix, $mimetypeArr)
                || (stripos($typeArr[0] . '/', $upload['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr)))
            )
        ) {
            $this->error(__('Uploaded file format is limited'));
        }
        $replaceArr = [
            '{year}'     => date("Y"),
            '{mon}'      => date("m"),
            '{day}'      => date("d"),
            '{hour}'     => date("H"),
            '{min}'      => date("i"),
            '{sec}'      => date("s"),
            '{random}'   => Random::alnum(16),
            '{random32}' => Random::alnum(32),
            '{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
            '{suffix}'   => $suffix,
            '{.suffix}'  => $suffix ? '.' . $suffix : '',
            '{filemd5}'  => md5_file($fileInfo['tmp_name']),
        ];
        $savekey = $upload['savekey'];
        $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);

        $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
        $fileName = substr($savekey, strripos($savekey, '/') + 1);
        //
        $splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
        if ($splInfo) {
            $imagewidth = $imageheight = 0;
            if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf'])) {
                $imgInfo = getimagesize($splInfo->getPathname());
                $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
                $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
            }
            $params = array(
                'admin_id'    => 0,
                'user_id'     => (int)$this->auth->id,
                'filesize'    => $fileInfo['size'],
                'imagewidth'  => $imagewidth,
                'imageheight' => $imageheight,
                'imagetype'   => $suffix,
                'imageframes' => 0,
                'mimetype'    => $fileInfo['type'],
                'url'         => $uploadDir . $splInfo->getSaveName(),
                'uploadtime'  => time(),
                'storage'     => 'local',
                'sha1'        => $sha1,
            );
            $attachment = model("attachment");
            $attachment->data(array_filter($params));
            $attachment->save();
            \think\Hook::listen("upload_after", $attachment);
//            $alioss = new Alioss();
            $site = \think\Config::get("site");
//            $alioss->uploadAfter($attachment);
            if($site['upload_way']==2){
                $res = $this->obsUpload(ROOT_PATH . 'public'.$params['url'],$fileName);
                $this->success(__('Upload successful'), [
                    'url' => $res['url'].'.'.$params['imagetype'],
                    'show_url'=>$res['show_url'],
                ]);
            }else{
                $this->success(__('Upload successful'), [
                    'url' => $uploadDir . $splInfo->getSaveName(),
                    'show_url'=>$site['file_url'].$uploadDir . $splInfo->getSaveName(),
                ]);
            }
        } else {
            // 上传失败获取错误信息
            $this->error($file->getError());
        }
    }

    public function obsUpload($file,$name){
        if(empty($file))$this->error('地址不可为空');
        $config = Config::get('obs');
        $obsClient = new ObsClient(['key'=>$config['key'],'secret'=>$config['secret'],'endpoint'=>$config['endpoint']]);
        try{
            $resp = $obsClient -> putObject([
                'Bucket' => $config['bucket'],
                'Key' => $name,
                'SourceFile'=>$file,
                'ContentType' => 'text/plain'
            ]);
            $res = $resp->toArray();
            if($res['Reason'] == "OK"){
                return ['url'=>trim($res['ETag'],'"'),'show_url'=>$res['ObjectURL']];
            }else{
                $this->error();
            }
        }catch (ObsException $obsException){
            $this->error('失败',$obsException->getExceptionMessage());
        }
    }

    /**
     * Notes: 省市区镇村单级列表
     * User: hawk
     * Email: 2271030162@qq.com
     * Date: 2019/6/18 0018
     * Time: 14:47
     */
    public function getAreaFiveList(){
        $type = input('type',0);
        $parent_id = input('parent_id',0);
        $areaModel = new AreaFour();
        $res = $areaModel->_getLevelList($type,$parent_id);
        if(empty($res))$this->error();
        $this->success('成功',$res);
    }

    /**
     * 读取省市区数据,联动列表
     */
    public function areaFour()
    {
        $params = $this->request->post();
        if (!empty($params)) {
            $province = isset($params['province_id']) ? $params['province_id'] : '';
            $city = isset($params['city_id']) ? $params['city_id'] : '';
            $area = isset($params['area_id']) ? $params['area_id'] : null;
            $town = isset($params['town_id']) ? $params['town_id'] : null;
        } else {
            $province = $this->request->post('province_id');
            $city = $this->request->post('city_id');
            $area = $this->request->post('area_id');
            $town = $this->request->post('town_id');
        }
        $where = ['pid' => 0, 'level' => 1];
        $provincelist = null;
        if ($province !== '') {
            if ($province) {
                $where['pid'] = $province;
                $where['level'] = 2;
            }
            if ($city !== '') {
                if ($city) {
                    $where['pid'] = $city;
                    $where['level'] = 3;
                }
                if($area!==''){
                    if($area){
                        $where['pid'] = $area;
                        $where['level'] = 4;
                    }
                    if($town!==''){
                        if($town){
                            $whereSite['town_id'] = $town;
                            $whereSite['site_level'] = 5;
                            $whereSite['is_check'] = '1';
                            $provincelist = Db::name('user')->where($whereSite)->field('id ,sitename')->select();
                            $this->success('',  $provincelist);
                        }
                    }
                }
            }
        }
        $provincelist = Db::name('area2')->where($where)->field('id ,name')->select();
        $this->success('',  $provincelist);
    }

    public function cityArea(){
        $city = $this->request->post('city_id');
        $where['pid'] = $city;
        $field = "id ,
                  name,
                  is_site,
                  site_id";
        $provincelist = Db::name('area2')->where($where)->field($field)->select();
        foreach ($provincelist as $k=>$v){
            $provincelist[$k]['child'] = Db::name('area2')->field($field)->where('pid',$v['id'])->where('is_site',1)->select();
        }
        $this->success('',  $provincelist);
    }

    /**
     * Notes: 站点查询
     * User: hawk
     * Email: 2271030162@qq.com
     * Date: 2019/7/10 0010
     * Time: 11:24
     */
    public function siteFive(){
        $params = $this->request->post();
        if (!empty($params)) {
            $province = isset($params['province_id']) ? $params['province_id'] : '';
            $city = isset($params['city_id']) ? $params['city_id'] : '';
            $area = isset($params['area_id']) ? $params['area_id'] : null;
            $town = isset($params['town_id']) ? $params['town_id'] : null;
        } else {
            $province = $this->request->post('province_id');
            $city = $this->request->post('city_id');
            $area = $this->request->post('area_id');
            $town = $this->request->post('town_id');
        }
        $where = ['a.pid' => 0];
        $joinStr = "u.province_id=a.id";
        $group   = "u.province_id";
        $where['a.level'] = 1;
        $provincelist = null;
        if ($province !== '') {
            if ($province) {
                $where['a.pid'] = $province;
                $where['a.level'] = 2;
                $joinStr = "u.city_id=a.id";
                $group   = "u.city_id";
            }
            if ($city !== '') {
                if ($city) {
                    $where['a.pid'] = $city;
                    $where['a.level'] = 3;
                    $joinStr = "u.area_id=a.id";
                    $group   = "u.area_id";
                }
                if($area!==''){
                    if($area){
                        $where['a.pid'] = $area;
                        $where['a.level'] = 4;
                        $joinStr = "u.town_id=a.id";
                        $group   = "u.town_id";
                    }
                    if($town!==''){
                        if($town){
                            $whereSite['town_id'] = $town;
                            $whereSite['site_level'] = 5;
                            $whereSite['site_type'] ='2';
                            $whereSite['is_check'] = '1';
                            $provincelist = Db::name('user')->where($whereSite)->field('id as site_id ,site_level,sitename')->select();
                            $this->success('',  $provincelist);
                        }
                    }
                }
            }
        }
        $provincelist = Db::name('area2')
            ->alias('a')
            ->field('
                a.id ,
                a.name,
                a.site_id,
                (select u.site_level from hawk_user u where '.$joinStr.' order by u.site_level limit 1) as site_level,
                (select u.sitename from hawk_user u where '.$joinStr.' order by u.site_level limit 1) as sitename,
                u.site_number
                ')
            ->join('user u',$joinStr,'LEFT')
            ->where('u.is_check','1')
            ->where('u.is_siter',1)
            ->where('u.site_type','1')
            ->where($where)
            ->group($group)
            ->select();
        $this->success('',  $provincelist);
    }

    /**
     * Notes: 验证账号是否重复
     * User: hawk
     * Email: 2271030162@qq.com
     * Date: 2019/6/18 0018
     * Time: 15:05
     */
    public function checkUsernameUnique(){
        $username = input('username');
        $reg = "^[_0-9a-z]{6,16}$";
        if (!Validate::regex($username, $reg)) {
            $this->error('登陆账号6-12位数字、字母、下划线');
        }
        $user = new \app\admin\model\User();
        $userInfo = $user->where('username',$username)->find();
        if($userInfo)$this->error('该账号已存在');
        $this->success('账号可使用');
    }

    public function hwsms(){
        //必填,请参考"开发准备"获取如下数据,替换为实际值
        $url = 'https://api.rtc.huaweicloud.com:10443/sms/batchSendSms/v1'; //APP接入地址+接口访问URI
        $APP_KEY = 'bG02Siqu87QZxC1r3nGVVRckN2iN'; //APP_Key
        $APP_SECRET = 'ba4Sa5c3rMW42E5h5URwwd6JMJ4A'; //APP_Secret
        $sender = '10690400999302551'; //国内短信签名通道号或国际/港澳台短信通道号
        $TEMPLATE_ID = 'ded038d835f24e6a8a686f99315797d9'; //模板ID

        //条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称
        //国际/港澳台短信不用关注该参数
        $signature = '华为云短信测试'; //签名名称

        //必填,全局号码格式(包含国家码),示例:+8615123456789,多个号码之间用英文逗号分隔
        $receiver = '+8615928010130'; //短信接收人号码

        //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
        $statusCallback = '';

        /**
         * 选填,使用无变量模板时请赋空值 $TEMPLATE_PARAS = '';
         * 单变量模板示例:模板内容为"您的验证码是${NUM_6}"时,$TEMPLATE_PARAS可填写为'["369751"]'
         * 双变量模板示例:模板内容为"您有${NUM_2}件快递请到${TXT_32}领取"时,$TEMPLATE_PARAS可填写为'["3","人民公园正门"]'
         * 查看更多模板格式规范:常见问题>业务规则>短信模板内容审核标准
         * @var string $TEMPLATE_PARAS
         */
        $TEMPLATE_PARAS = '["123456"]'; //模板变量

        //请求Headers
        $headers = [
            'Content-Type: application/x-www-form-urlencoded',
            'Authorization: WSSE realm="SDP",profile="UsernameToken",type="Appkey"',
            'X-WSSE: ' . buildWsseHeader($APP_KEY, $APP_SECRET)
        ];
        //请求Body
        $data = http_build_query([
            'from' => $sender,
            'to' => $receiver,
            'templateId' => $TEMPLATE_ID,
            'templateParas' => $TEMPLATE_PARAS,
            'statusCallback' => $statusCallback,
            'signature' => $signature //使用国内短信通用模板时,必须填写签名名称
        ]);

        $context_options = [
            'http' => ['method' => 'POST', 'header'=> $headers, 'content' => $data],
            'ssl' => ['verify_peer' => false, 'verify_peer_name' => false] //为防止因HTTPS证书认证失败造成API调用失败，需要先忽略证书信任问题
        ];
        //print_r($context_options) . PHP_EOL; //打印请求信息
        $response = juhecurl($url,$data,1,$headers);

        dump(json_decode($response,true));die;
    }
}
